package com.py.payment.running;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.py.payment.entity.*;
import com.py.payment.nettys.constant.MessageConstant;
import com.py.payment.nettys.server.ChannelMap;
import com.py.payment.service.*;
import com.py.payment.tools.ToolsUtils;
import com.py.payment.tools.date.DateUtils;
import com.py.payment.tools.dtu.CharacterConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class TimeRun {

    @Autowired
    private PySiteService siteService;

    @Autowired
    private PyIngredientsService ingredientsService;

    @Autowired
    private PySiteNumericService siteNumericService;

    @Autowired
    private PointPositionService pointPositionService;

    @Autowired
    private PyIngredientsRecordService ingredientsRecordService;

    private List<PointPosition> positionList;

    /**
     * 定时每3分钟采集一次数据
     */
    @Scheduled(cron ="0 0/3 * * * ?")
    public void sensorDataCollection(){
        if(ToolsUtils.isEmpty(positionList)){
            positionList = this.pointPositionService.list();
        }

        log.info("现在是{}，新一轮数据采集开始......", DateUtils.dateToDateStr(new Date(),DateUtils.YYYY_MM_DD_HH_MM_SS));
        if(ChannelMap.getChannelMap().size()<1){
            log.info("目前没有连接的设备,故而跳过本次采集");
        }
        for (PointPosition position : positionList) {
            if (ToolsUtils.isEmpty(position.getDeviceId())) {
                continue;
            }
            StringBuffer sb = new StringBuffer();
            sb.append(MessageConstant.commandFrameEndingPrefix);
            sb.append(MessageConstant.commandBytes);
            sb.append(MessageConstant.reserveBytes);
            sb.append(position.getDeviceId());
            sb.append(DateUtils.dateToDateStr(new Date(), "yyMMddHHmmss"));
            String code = sb.toString();
            int size = code.length() / 2;
            int x = 0;
            int y = 2;
            List<String> list = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                list.add(code.substring(x, y));
                x = y;
                y = y + 2;
            }
            String checkCode = "";
            for (int i = 0; i < list.size(); i++) {
                if (ToolsUtils.isEmpty(checkCode)) {
                    checkCode = list.get(i);
                } else {
                    checkCode = CharacterConvertUtils.xor(checkCode, list.get(i));
                }
            }
            sb.append(checkCode);
            code = sb.toString();
            try{
                ChannelMap.pushNewsToAllClient(code);
                // 避免发送数据时间间隔太短导致接收端数据字节拼接到一起
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 定时每5分钟生成一次成分记录 (暂时停掉,待后续对接传感器数据)
     */
//    @Scheduled(cron ="* */5 * * * ?")
    public void generateIngredientsRecord(){
        Date date = new Date();
        List<PyIngredientsRecord> records = new ArrayList<>();
        List<PySite> siteList = this.siteService.list();
        List<PyIngredients> ingredientsList = this.ingredientsService.list();
        siteList.forEach(site->{
            ingredientsList.forEach(item->{
                QueryWrapper<PySiteNumeric> qw = new QueryWrapper<>();
                qw.eq("site_id", site.getId());
                qw.eq("ingredient_id", item.getId());
                qw.orderByDesc("id");
                qw.last("limit 1");
                PySiteNumeric siteNumeric = this.siteNumericService.getOne(qw);
                PyIngredientsRecord ingredientsRecord = new PyIngredientsRecord();
                ingredientsRecord.setSiteId(site.getId());
                ingredientsRecord.setInvestmentId(item.getId());
                ingredientsRecord.setPredefinedNumber(siteNumeric.getNumericValue());
                ingredientsRecord.setNumericValue(generateNumeric(siteNumeric.getNumericValue()));
                ingredientsRecord.setCreateTime(date);
                records.add(ingredientsRecord);
            });
        });
        this.ingredientsRecordService.saveBatch(records);
    }

    public String generateNumeric(String predefinedNumber){
        BigDecimal numeric = new BigDecimal(predefinedNumber);
        Random numericRandom = new Random();
        double randomNumeric = numericRandom.nextDouble() * 2;
        BigDecimal n = new BigDecimal(randomNumeric).setScale(2, RoundingMode.HALF_UP);
        Random random = new Random();
        int negative = 25;
        int positive = 25;
        int randomNumber = random.nextInt(100);
        if (randomNumber < negative) {
            numeric = numeric.subtract(n);
        } else if (randomNumber < negative + positive) {
            numeric = numeric.add(n);
        }
        return numeric.setScale(2,RoundingMode.HALF_UP).toPlainString();
    }

}
